"""
扫描记录价格分析模块
"""
from typing import Dict, List, Optional, Any, Tuple
from datetime import datetime, timedelta
import statistics
import json  # 需要用来解析 price_list
import numpy as np
from sklearn.cluster import KMeans
from collections import Counter, defaultdict
from com.db.scan_record_manager import ScanRecordManager
from com.db.scan_record_price_analysis_manager import ScanRecordPriceAnalysisManager
from com.db.task_manager import TaskManager
from com.db.order_account_manager import OrderAccountManager
from com.db.profit_rate_price_manager import ProfitRatePriceManager
from com.utils.logger import get_logger
from reqapi.get_template_info import GetTemplateInfoApi
import math

logger = get_logger("ScanRecordPriceAnalyzer")

class DateTimeEncoder:
    """处理 datetime 对象的 JSON 编码器"""
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        return obj

class ScanRecordPriceAnalyzer:
    """扫描记录价格分析器"""
    
    def __init__(self, price_analysis_manager=None):
        """
        初始化扫描记录价格分析器
        
        Args:
            price_analysis_manager: 价格分析管理器实例
        """
        if price_analysis_manager is None:
            from com.db.scan_record_price_analysis_manager import ScanRecordPriceAnalysisManager
            self.price_analysis_manager = ScanRecordPriceAnalysisManager()
        else:
            self.price_analysis_manager = price_analysis_manager
            
        # 初始化参考价来源统计信息
        self.reference_price_source_stats = {
            '常卖价替代': 0,
            '原始': 0,
            '总数': 0
        }
        
        self.scan_record_manager = ScanRecordManager()
        self.price_analysis_manager = ScanRecordPriceAnalysisManager()
        self.task_manager = TaskManager()
        self.order_account_manager = OrderAccountManager()
        self.price_frequency = Counter()  # 初始化价格频率计数器
        self.profit_rate_price_manager = ProfitRatePriceManager()  # 初始化利润率价格变动记录管理器
        
        # 从order_account表中随机获取一个可用账号
        active_accounts = self.order_account_manager.get_active_accounts()
        if not active_accounts:
            logger.warning("没有可用的下单账号，部分功能可能无法使用")
            self.template_info_api = None
        else:
            import random
            account = random.choice(active_accounts)
            
            # 初始化API客户端
            self.template_info_api = GetTemplateInfoApi(
                device_id=account['device_id'],
                device_token=account['device_id'],
                auth_token=f"Bearer {account['uu_token']}" if not account['uu_token'].startswith('Bearer ') else account['uu_token'],
                uk=account['uk']
            )
        
    def analyze_price_distribution(self, prices):
        """
        使用聚类方法分析价格分布
        """
        if not prices:
            return [], {}

        # 将价格转换为二维数组（sklearn要求的格式）
        X = np.array(prices).reshape(-1, 1)
        
        # 使用手肘法则确定最佳聚类数
        max_clusters = min(5, len(set(prices)))  # 最多5个聚类
        if max_clusters < 2:
            return [], {}
            
        # 计算不同聚类数的SSE（误差平方和）
        sse = []
        for k in range(2, max_clusters + 1):
            kmeans = KMeans(n_clusters=k, random_state=42)
            kmeans.fit(X)
            sse.append(kmeans.inertia_)
        
        # 找到最佳聚类数（手肘点）
        if len(sse) > 1:
            # 计算SSE曲线的斜率变化
            diffs = np.diff(sse)
            if len(diffs) > 1:  # 确保diffs长度大于1
                diff_r = diffs[1:] / diffs[:-1]
                if len(diff_r) > 0:  # 确保diff_r不为空
                    # 找到斜率变化最大的点
                    elbow = np.argmax(diff_r) + 2
                else:
                    elbow = 2
            else:
                elbow = 2
        else:
            elbow = 2
            
        # 使用最佳聚类数进行聚类
        kmeans = KMeans(n_clusters=elbow, random_state=42)
        kmeans.fit(X)
        
        # 获取每个聚类的统计信息
        clusters = []
        labels = kmeans.labels_
        unique_labels = np.unique(labels)
        
        for label in unique_labels:
            cluster_prices = X[labels == label].flatten()
            cluster_info = {
                'min_price': float(np.min(cluster_prices)),
                'max_price': float(np.max(cluster_prices)),
                'mean_price': float(np.mean(cluster_prices)),
                'median_price': float(np.median(cluster_prices)),
                'count': len(cluster_prices),
                'percentage': len(cluster_prices) / len(prices) * 100
            }
            clusters.append(cluster_info)
            
        # 按平均价格排序
        clusters.sort(key=lambda x: x['mean_price'])
        
        # 构建价格区间统计
        ranges = {}
        for cluster in clusters:
            range_key = f"{cluster['min_price']:.2f}-{cluster['max_price']:.2f}"
            ranges[range_key] = cluster['count']
            
        return clusters, ranges

    def identify_price_segments(self, clusters: List[Dict]) -> tuple:
        """
        识别价格段（常规、波动、异常）
        
        Args:
            clusters: 聚类结果列表
            
        Returns:
            Tuple[Dict, Dict, List[Dict]]: (常规价格段，波动价格段，异常价格段列表)
        """
        if not clusters:
            return None, None, []
        
        # 按数量排序
        sorted_clusters = sorted(clusters, key=lambda x: x['count'], reverse=True)
        
        # 找出最大的聚类作为常规价格段
        normal_segment = sorted_clusters[0]
        normal_price_range = (normal_segment['min_price'], normal_segment['max_price'])
        
        # 计算总记录数
        total_count = sum(self.price_frequency.values())
        
        other_segments = []
        for cluster in sorted_clusters[1:]:
            # 计算与常规价格段的最小价格的差异百分比
            price_diff_percent = (normal_segment['min_price'] - cluster['min_price']) / normal_segment['min_price'] * 100
            
            # 检查这个聚类中是否有高频价格
            has_high_frequency_price = False
            for price, count in self.price_frequency.items():
                # 如果价格在这个聚类范围内
                if cluster['min_price'] <= price <= cluster['max_price']:
                    # 如果某个价格出现次数超过10%
                    if count / total_count >= 0.1:
                        has_high_frequency_price = True
                        break
            
            # 只有在没有高频价格且价格差异大于阈值时，才标记为异常
            if price_diff_percent > 5 and not has_high_frequency_price:
                cluster['type'] = 'abnormal'
                other_segments.append(cluster)
            else:
                cluster['type'] = 'fluctuation'
                other_segments.append(cluster)
        
        # 分离波动价格段和异常价格段
        fluctuation_segments = [s for s in other_segments if s['type'] == 'fluctuation']
        abnormal_segments = [s for s in other_segments if s['type'] == 'abnormal']
        
        # 如果有波动价格段，返回第一个（按数量最多的）
        fluctuation_segment = fluctuation_segments[0] if fluctuation_segments else None
        
        return normal_segment, fluctuation_segment, abnormal_segments
        
    def get_abnormal_prices(self, prices: List[float], clusters: List[Dict], reference_price: float) -> List[float]:
        """
        根据与扫货参考价的利润率识别异常价格
        
        Args:
            prices: 价格列表
            clusters: 聚类结果列表（已不再使用）
            reference_price: 扫货参考价格
            
        Returns:
            List[float]: 异常价格列表
        """
        if not prices or reference_price <= 0:
            return []
            
        # 识别异常低价（利润率超过5%的价格）
        abnormal_prices = []
        for price in prices:
            price = round(price, 2)
            if price > 0 and price < reference_price:
                profit_rate = (reference_price - price) / price * 100
                if profit_rate >= 5:  # 利润率大于等于5%
                    abnormal_prices.append(price)
                    
        return abnormal_prices

    def analyze_prices(self, prices: List[float], reference_price: float = None) -> Dict[str, Any]:
        """
        分析价格数据
        
        Args:
            prices: 价格列表
            reference_price: 扫货参考价格，如果提供则使用此价格作为基准
            
        Returns:
            Dict: 分析结果
        """
        if not prices:
            return None
            
        # 计算价格频率
        self.price_frequency = Counter([round(p, 2) for p in prices])
            
        # 基础统计
        mean_price = statistics.mean(prices)
        median_price = statistics.median(prices)
        std_dev = statistics.stdev(prices) if len(prices) > 1 else 0
        
        # 设置最小标准差为均价的0.5%
        min_std_dev = mean_price * 0.005
        if std_dev < min_std_dev:
            std_dev = min_std_dev
            
        # 计算价格离散度
        price_variance = std_dev / mean_price if mean_price > 0 else 0
        
        # 根据价格大小动态调整标准差倍数
        # 价格越高，标准差倍数越大
        # 小于100元用2个标准差
        # 100-500元用2.5个标准差
        # 500-2000元用3个标准差
        # 2000元以上用3.5个标准差
        if mean_price < 100:
            std_multiplier = 2
        elif mean_price < 500:
            std_multiplier = 2.5
        elif mean_price < 2000:
            std_multiplier = 3
        else:
            std_multiplier = 3.5
            
        # 识别异常低价（利润率超过5%的价格）
        clusters, ranges = self.analyze_price_distribution(prices)
        
        # 计算常规售价（价格众数）
        rounded_prices = [round(p, 2) for p in prices]
        price_counts = Counter(rounded_prices)
        if not price_counts:
            return None
        common_price = price_counts.most_common(1)[0][0]
        
        # 计算标准差
        std_dev = statistics.stdev(prices) if len(prices) > 1 else 0
        
        # 计算价格分布
        price_distribution = {
            'clusters': clusters,
            'cluster_ranges': ranges
        }
        
        # 使用渐进式方法调整常卖价
        final_common_price = self.adjust_common_sell_price(prices, common_price)
        
        # 如果提供了扫货参考价，则使用它作为基准，否则使用常卖价
        base_price = reference_price if reference_price is not None else final_common_price
        
        # 分析价格频率分布，筛选出最具代表性的价格
        total_count = sum(price_counts.values())
        top_prices = []
        
        # 设置价格范围（基准价±3个标准差）
        price_lower_bound = base_price - (3 * std_dev)
        price_upper_bound = base_price + (3 * std_dev)
        
        # 获取在价格范围内的所有价格及其出现次数
        for price, count in price_counts.items():
            if price_lower_bound <= price <= price_upper_bound:
                percentage = (count / total_count) * 100
                top_prices.append({
                    "price": price,
                    "count": count,
                    "percentage": round(percentage, 2)
                })
        
        # 按价格降序排序
        top_prices.sort(key=lambda x: x['price'], reverse=True)
        
        # 如果没有找到任何符合条件的价格，至少保留基准价
        if not top_prices:
            percentage = (price_counts[base_price] / total_count * 100) if base_price in price_counts else 0
            top_prices.append({
                "price": base_price,
                "count": price_counts.get(base_price, 0),
                "percentage": round(percentage, 2)
            })
        
        # 计算异常价格
        abnormal_prices = self.get_abnormal_prices(prices, clusters, base_price)
        abnormal_price_counts = Counter(abnormal_prices)
        
        return {
            'price_variance': round(price_variance, 4),
            'abnormal_price_counts': dict(abnormal_price_counts),
            'top_price_list': top_prices,
            'common_sell_price': final_common_price,
            'historical_low': min(prices),
            'price_distribution': price_distribution,  
            'selling_count': None,
            'record_count': len(prices),  # 添加统计数据条数
            'scan_reference_price': None,  # 添加扫货参考价格
        }
    
    def adjust_common_sell_price(self, prices: List[float], initial_common_price: float) -> float:
        """
        通过分析价格离散度和分布特征来调整常卖价
        
        对于离散度低（<3%）的情况，使用滑动窗口寻找最密集价格区间的中位数
        对于离散度高的情况，使用渐进式搜索策略
        
        Args:
            prices: 价格列表
            initial_common_price: 初始常卖价
            
        Returns:
            float: 调整后的常卖价
        """
        if not prices or initial_common_price <= 0:
            return initial_common_price
            
        # 计算标准差和离散度
        mean_price = statistics.mean(prices)
        std_dev = statistics.stdev(prices) if len(prices) > 1 else 0
        price_variance = std_dev / mean_price if mean_price > 0 else 0
        
        if std_dev == 0:
            return initial_common_price
            
        # 如果离散度小于3%，使用集中趋势策略
        LOW_VARIANCE_THRESHOLD = 0.03  # 3%
        if price_variance < LOW_VARIANCE_THRESHOLD:
            # 找出主要价格区间
            prices_sorted = sorted(prices)
            window_size = max(3, len(prices) // 10)  # 使用滑动窗口找最密集区间
            max_density = 0
            best_price = initial_common_price
            
            for i in range(len(prices) - window_size + 1):
                window_prices = prices_sorted[i:i + window_size]
                window_density = len(window_prices) / (window_prices[-1] - window_prices[0] + 0.0001)
                
                if window_density > max_density:
                    max_density = window_density
                    # 使用窗口中位数作为候选价格
                    best_price = statistics.median(window_prices)
            
            # 如果最佳价格偏离初始价格太多，保持初始价格
            deviation = abs(best_price - initial_common_price) / initial_common_price
            MAX_LOW_VARIANCE_DEVIATION = 0.05  # 低离散度情况下的最大允许偏离度（5%）
            if deviation > MAX_LOW_VARIANCE_DEVIATION:
                return initial_common_price
                
            return best_price
            
        # 对于离散度较高的情况，使用渐进式策略
        MAX_DEVIATION = 0.10  # 最大允许偏离度（10%）
        MIN_DENSITY_RATIO = 0.70  # 最小密度要求（70%）
        MIN_SAMPLE_COUNT = 3  # 最小样本数要求
        
        current_common_price = initial_common_price
        current_lower_bound = initial_common_price
        total_samples = len(prices)
        
        while True:
            # 计算新的下界
            new_lower_bound = current_lower_bound - std_dev
            
            # 计算当前区间的样本密度和样本数
            current_range_samples = [p for p in prices if current_lower_bound <= p < current_common_price]
            current_sample_count = len(current_range_samples)
            current_density = current_sample_count / total_samples if total_samples > 0 else 0
            
            # 找出在新区间的所有价格
            prices_in_range = [p for p in prices if new_lower_bound <= p < current_common_price]
            if not prices_in_range:
                break
                
            # 计算新区间的样本数和密度
            new_sample_count = len(prices_in_range)
            new_density = new_sample_count / total_samples if total_samples > 0 else 0
            
            # 找出区间内的最小价格作为候选新常卖价
            candidate_price = min(prices_in_range)
            
            # 计算候选价格与初始价格的偏离度
            deviation = abs(candidate_price - initial_common_price) / initial_common_price
            
            # 如果偏离太大或密度太低或样本数不足，停止搜索
            if (deviation > MAX_DEVIATION or 
                new_density < current_density * MIN_DENSITY_RATIO or 
                new_sample_count < MIN_SAMPLE_COUNT):
                break
                
            # 更新常卖价和区间下界
            current_common_price = candidate_price
            current_lower_bound = new_lower_bound
            
        return current_common_price

    def calculate_scan_reference_price(self, clusters: List[Dict], common_sell_price: float, normal_price: float = None) -> Optional[float]:
        """
        计算扫货参考价格
        
        根据价格聚类结果和常卖价格，计算扫货参考价格。
        扫货参考价格定义为：常卖价所在分段的更低一个价格分段中的众数价格。
        如果常卖价在最低价格分段或者没有更低的价格分段，则在常卖价所在分段内寻找比常卖价小的、比较聚集的价格段的众数。
        如果没有找到合适的价格，则使用常卖价作为扫货参考价格。
        
        Args:
            clusters: 价格聚类结果
            common_sell_price: 常卖价格
            normal_price: 官方最低价格（不再使用）
            
        Returns:
            float: 扫货参考价格
        """
        if not clusters or not common_sell_price:
            logger.warning("无法计算扫货参考价格：聚类结果为空或常卖价格无效")
            return common_sell_price
        
        # 按价格范围从低到高排序聚类
        sorted_clusters = sorted(clusters, key=lambda x: x['min_price'])
        
        # 找到常卖价所在的分段
        common_price_segment_index = None
        for i, cluster in enumerate(sorted_clusters):
            if cluster['min_price'] <= common_sell_price <= cluster['max_price']:
                common_price_segment_index = i
                logger.info(f"常卖价 {common_sell_price} 在分段 {i+1}: {cluster['min_price']}-{cluster['max_price']}")
                break
        
        # 如果没有找到常卖价所在分段（理论上不应该发生），使用常卖价作为扫货参考价格
        if common_price_segment_index is None:
            logger.warning(f"常卖价 {common_sell_price} 不在任何分段内，使用常卖价作为扫货参考价格")
            return common_sell_price
        
        # 如果常卖价在最低价格分段，尝试在当前分段内寻找更低价格
        if common_price_segment_index == 0:
            logger.info(f"常卖价 {common_sell_price} 在最低价格分段，尝试在当前分段内寻找更低价格")
            
            # 获取常卖价所在分段
            current_segment = sorted_clusters[common_price_segment_index]
            
            # 从价格频率计数器中筛选出该分段内比常卖价小的价格
            lower_prices = {}
            for price, count in self.price_frequency.items():
                if current_segment['min_price'] <= price < common_sell_price:
                    lower_prices[price] = count
            
            # 如果没有比常卖价小的价格，使用常卖价作为扫货参考价格
            if not lower_prices:
                logger.info(f"常卖价 {common_sell_price} 所在分段内没有更低价格，使用常卖价作为扫货参考价格")
                return common_sell_price
            
            # 计算比常卖价小的价格中的众数作为扫货参考价格
            most_common_price = max(lower_prices.items(), key=lambda x: x[1])[0]
            logger.info(f"从常卖价所在分段中找到比常卖价小的众数价格: {most_common_price}")
            
            return most_common_price
        
        # 获取常卖价下一个更低的价格分段
        lower_segment = sorted_clusters[common_price_segment_index - 1]
        logger.info(f"常卖价的下一个更低价格分段: {lower_segment['min_price']}-{lower_segment['max_price']}")
        
        # 从价格频率计数器中筛选出该分段内的价格
        segment_prices = []
        for price in self.price_frequency.keys():
            if lower_segment['min_price'] <= price <= lower_segment['max_price']:
                segment_prices.extend([price] * self.price_frequency[price])
        
        # 如果该分段内没有价格数据，尝试在常卖价所在分段内寻找更低价格
        if not segment_prices:
            logger.info(f"常卖价的下一个更低价格分段内没有价格数据，尝试在当前分段内寻找更低价格")
            
            # 获取常卖价所在分段
            current_segment = sorted_clusters[common_price_segment_index]
            
            # 从价格频率计数器中筛选出该分段内比常卖价小的价格
            lower_prices = {}
            for price, count in self.price_frequency.items():
                if current_segment['min_price'] <= price < common_sell_price:
                    lower_prices[price] = count
            
            # 如果没有比常卖价小的价格，使用常卖价作为扫货参考价格
            if not lower_prices:
                logger.info(f"常卖价 {common_sell_price} 所在分段内没有更低价格，使用常卖价作为扫货参考价格")
                return common_sell_price
            
            # 计算比常卖价小的价格中的众数作为扫货参考价格
            most_common_price = max(lower_prices.items(), key=lambda x: x[1])[0]
            logger.info(f"从常卖价所在分段中找到比常卖价小的众数价格: {most_common_price}")
            
            return most_common_price
        
        # 计算该分段内价格的众数作为扫货参考价格
        segment_price_counter = Counter(segment_prices)
        most_common_price = segment_price_counter.most_common(1)[0][0]
        logger.info(f"从常卖价的下一个更低价格分段中计算得到扫货参考价格: {most_common_price}")
        
        return most_common_price

    def analyze_goods(self, goods_id: int, period: str = '24h') -> Optional[Dict[str, Any]]:
        """
        分析商品价格
        
        Args:
            goods_id: 商品ID
            period: 分析周期（24h/7d）
            
        Returns:
            Optional[Dict]: 分析结果
        """
        try:
            # 初始化参考价来源统计，确保每次分析都有新的统计数据
            self.reference_price_source_stats = {
                '常卖价替代': 0,
                '原始': 0,
                '总数': 0
            }
            
            # 获取商品信息（只获取启用状态的任务）
            task = self.task_manager.get_task_by_goods_id(goods_id)
            if not task or task.get('status') != 1:
                logger.warning(f"未找到商品信息或任务未启用: {goods_id}")
                return None
                
            # 获取扫描记录（根据时间周期限制）
            hours = 24 if period == '24h' else 168
            start_time = datetime.now() - timedelta(hours=hours)
            records = self.scan_record_manager.get_records_by_goods_id(
                goods_id=goods_id,
                start_time=start_time
            )
            logger.info(f"获取到 {len(records) if records else 0} 条扫描记录")
            
            if not records:
                logger.warning(f"未找到商品 {goods_id} 的扫描记录")
                return None

            # 获取记录的时间范围
            scan_times = [
                datetime.strptime(record['scan_start_time'], '%Y-%m-%d %H:%M:%S') 
                if isinstance(record['scan_start_time'], str) 
                else record['scan_start_time'] 
                for record in records
            ]
            earliest_time = min(scan_times)
            latest_time = max(scan_times)
            
            # 收集所有价格数据和在售数量
            all_prices = []
            selling_counts = []
            
            for record in records:
                # 统计在售数量
                if record.get('selling_count') is not None:
                    selling_counts.append(record['selling_count'])
                
                # 首先尝试从 price_list 获取详细价格
                if record.get('price_list'):
                    try:
                        if isinstance(record['price_list'], str):
                            prices = json.loads(record['price_list'])
                        elif isinstance(record['price_list'], list):
                            prices = record['price_list']
                        else:
                            logger.warning(f"未知的 price_list 类型: {type(record['price_list'])}")
                            continue
                        all_prices.extend(prices)
                        continue
                    except json.JSONDecodeError:
                        logger.warning(f"解析价格列表失败: {record['price_list']}")
                
                # 如果没有 price_list，使用 min_price、max_price 和 avg_price
                if record.get('min_price') is not None:
                    all_prices.append(record['min_price'])
                if record.get('max_price') is not None and record['max_price'] != record.get('min_price'):
                    all_prices.append(record['max_price'])
                if record.get('avg_price') is not None and record['avg_price'] not in [record.get('min_price'), record.get('max_price')]:
                    all_prices.append(record['avg_price'])
            
            if not all_prices:
                logger.warning(f"未找到价格数据: {goods_id}")
                return None
                
            logger.info(f"收集到 {len(all_prices)} 个价格数据点")
            
            # 计算平均在售数量
            avg_selling_count = round(sum(selling_counts) / len(selling_counts)) if selling_counts else None
            
            # 使用聚类方法分析价格分布
            clusters, ranges = self.analyze_price_distribution(all_prices)
            
            # 计算价格离散度
            if not all_prices:
                logger.warning(f"没有有效的价格数据: {goods_id}")
                return None
                
            mean_price = statistics.mean(all_prices)
            std_dev = statistics.stdev(all_prices) if len(all_prices) > 1 else 0
            price_variance = std_dev / mean_price if mean_price > 0 else 0
            
            if clusters:
                normal_segment = clusters[0]
                common_sell_price = normal_segment['median_price']
            else:
                common_sell_price = statistics.median(all_prices) if all_prices else 0
                
            if common_sell_price <= 0:
                logger.warning(f"计算得到的常卖价无效: {goods_id}")
                return None
                
            # 使用渐进式方法调整常卖价
            common_sell_price = self.adjust_common_sell_price(all_prices, common_sell_price)
            
            # 计算扫货参考价格
            # 重置价格频率计数器，确保每次分析时都是新的计数
            self.price_frequency = Counter(all_prices)
            normal_price = None
            try:
                # 随机等待1-3秒
                import random
                import time
                wait_time = random.uniform(3, 10)
                time.sleep(wait_time)
                
                # 添加详细日志
                logger.info(f"开始获取商品 {goods_id} 的模板信息")
                
                # 记录请求参数
                logger.info(f"请求参数: goods_id={goods_id}")
                
                # 检查 template_info_api 是否为 None
                if self.template_info_api is None:
                    logger.warning(f"template_info_api 为 None，无法获取商品 {goods_id} 的模板信息")
                    normal_price = None
                else:
                    template_response = self.template_info_api.execute(goods_id)
                    
                    # 记录响应内容
                    if template_response:
                        logger.info(f"获取商品 {goods_id} 的模板信息成功")
                        logger.info(f"响应内容: {template_response}")
                        
                        if hasattr(template_response, 'TemplateInfo'):
                            logger.info(f"模板信息: {template_response.TemplateInfo}")
                            
                            # 记录MinPrice字段
                            if hasattr(template_response.TemplateInfo, 'MinPrice'):
                                logger.info(f"最低价格: {template_response.TemplateInfo.MinPrice}")
                            else:
                                logger.warning(f"模板信息中没有MinPrice字段")
                        else:
                            logger.warning(f"响应中没有TemplateInfo字段")
                    else:
                        logger.warning(f"获取商品 {goods_id} 的模板信息失败，响应为None")
                        
                    if template_response and template_response.TemplateInfo:
                        # 确保normal_price是浮点数类型
                        try:
                            normal_price = float(template_response.TemplateInfo.MinPrice)
                            logger.info(f"成功转换最低价格为浮点数: {normal_price}")
                        except (ValueError, TypeError):
                            logger.warning(f"商品 {goods_id} 的模板最低价格无法转换为浮点数: {template_response.TemplateInfo.MinPrice}")
                            normal_price = None
                    else:
                        logger.warning(f"获取商品 {goods_id} 的模板信息失败")
            except Exception as e:
                logger.error(f"获取商品 {goods_id} 的模板信息时出错: {str(e)}")
                logger.error(f"错误类型: {type(e).__name__}")
                import traceback
                logger.error(f"详细错误信息: {traceback.format_exc()}")
                normal_price = None
            scan_reference_price = self.calculate_scan_reference_price(clusters, common_sell_price, normal_price)
            
            # 使用扫货参考价识别异常价格
            abnormal_prices = self.get_abnormal_prices(all_prices, clusters, scan_reference_price)
            abnormal_price_counts = Counter(abnormal_prices)
            
            # 将异常价格计数转换为指定格式，并按价格升序排序
            abnormal_prices_list = [
                {
                    "price": price, 
                    "count": count,
                    "profit_rate": round((scan_reference_price - price) / price * 100, 2) if price > 0 else 0  # 使用扫货参考价计算利润率
                }
                for price, count in abnormal_price_counts.items()
            ]
            abnormal_prices_list.sort(key=lambda x: x['price'])  # 按价格升序排序
            
            # 计算价格分布
            price_distribution = {
                'clusters': clusters,
                'cluster_ranges': ranges
            }
            
            # 分析活动时间分布
            activity_distribution = self.analyze_time_distribution(records)
            
            # 分析异常价格的时间分布
            abnormal_price_distribution = self.analyze_abnormal_price_time_distribution(
                records=records,
                abnormal_prices=abnormal_prices
            )
            
            # 构建分析记录
            analysis_data = {
                'goods_id': goods_id,
                'goods_name': task.get('name', ''),
                'hash_name': task.get('hash_name', ''),
                'wear': task.get('wear', '-'),
                'exterior': task.get('exterior', ''),
                'rarity': task.get('rarity', ''),
                'quality': task.get('quality', ''),
                'analysis_time': datetime.now(),
                'analysis_period': period,
                'earliest_record_time': earliest_time,
                'latest_record_time': latest_time,
                'abnormal_price_time_distribution': abnormal_price_distribution,  
                'activity_time_distribution': activity_distribution,  
                'price_variance': price_variance,
                'abnormal_prices': abnormal_prices_list,  
                'top_price_list': self.analyze_prices(all_prices, scan_reference_price)['top_price_list'],  # 添加出现次数最多的价格列表
                'common_sell_price': common_sell_price,
                'normal_price': normal_price,
                'historical_low': min(all_prices),
                'price_distribution': price_distribution,  
                'selling_count': avg_selling_count,
                'record_count': len(records),  # 添加统计数据条数
                'scan_reference_price': scan_reference_price,  # 添加扫货参考价格
            }
            
            # 检查任务的pricing_type，如果是动态利润率(1)，则根据利润率计算真实的捡漏价格
            if task.get('pricing_type') == 1 and task.get('profit_rate') is not None and scan_reference_price > 0:
                profit_rate = task.get('profit_rate') / 100.0  # 将百分比转换为小数
                
                # 获取用户设置的最小利润率（如果有的话）
                min_profit_rate = None
                if task.get('min_profit_rate') is not None and task.get('min_profit_rate') > 0:
                    min_profit_rate = task.get('min_profit_rate') / 100.0  # 将百分比转换为小数
                
                # 使用带上下限的扫货价格计算方法
                snipe_price_result = self.calculate_bounded_snipe_price(
                    goods_id=goods_id,
                    scan_reference_price=scan_reference_price,
                    profit_rate=profit_rate,
                    normal_price=normal_price,
                    custom_min_profit_rate=min_profit_rate,  # 传递用户设置的最小利润率
                    common_sell_price=common_sell_price  # 传递常卖价
                )
                
                real_snipe_price = snipe_price_result['snipe_price']
                target_sell_price = scan_reference_price
                remark = snipe_price_result['remark']
                
                logger.info(f"任务使用固定利润率定价: 商品ID={goods_id}, 利润率={task.get('profit_rate')}%, "
                           f"扫货参考价={scan_reference_price}, 计算得到的真实扫货价={real_snipe_price}")
                
                # 更新任务的捡漏价和目标售价
                self.task_manager.update_task_prices(
                    task_id=task.get('id'),
                    buy_price_limit=real_snipe_price,
                    target_sell_price=target_sell_price
                )
                logger.info(f"已更新任务的捡漏价和目标售价: 任务ID={task.get('id')}, "
                           f"捡漏价={real_snipe_price}, 目标售价={target_sell_price}")
                
                # 获取推算利润率，并将其转换为百分比形式（如0.05转为5.0）
                estimated_profit_rate = snipe_price_result.get('estimated_profit_rate', 0.0)
                estimated_profit_rate_percent = round(estimated_profit_rate * 100, 2)
                
                # 更新任务的利润率为推算利润率
                self.task_manager.update_task_profit_rate(
                    task_id=task.get('id'),
                    profit_rate=estimated_profit_rate_percent
                )
                logger.info(f"已更新任务的利润率为推算利润率: 任务ID={task.get('id')}, "
                           f"原利润率={task.get('profit_rate')}%, 新利润率={estimated_profit_rate_percent}%")
                
                # 在利润率价格变动表中添加一条自动调整记录
                profit_rate = task.get('profit_rate') if task.get('profit_rate') is not None else 0
                record_data = {
                    'goods_id': goods_id,
                    'goods_name': task.get('name', ''),
                    'hash_name': task.get('hash_name', ''),
                    'profit_rate': profit_rate,
                    'buy_price': real_snipe_price,
                    'target_sell_price': target_sell_price,
                    'operator': 'system',
                    'remark': remark,
                    'modify_type': 1,  # 1: 自动调整
                    'pricing_type': task.get('pricing_type', 1),
                    'base_snipe_price': snipe_price_result.get('base_snipe_price'),
                    'common_sell_price': common_sell_price,
                    'normal_price': normal_price,
                    'adjustment_factor': max(snipe_price_result.get('upper_adjust_factor', 0), 
                                           snipe_price_result.get('lower_adjust_factor', 0)),
                    'price_variance': snipe_price_result.get('price_variance', 0),
                    'upper_bound_price': snipe_price_result.get('adjusted_upper_bound'),
                    'lower_bound_price': snipe_price_result.get('adjusted_lower_bound'),
                    'min_required_gap': snipe_price_result.get('min_required_gap'),
                    'actual_price_gap_ratio': snipe_price_result.get('actual_price_gap_ratio'),
                    'history_data_count': snipe_price_result.get('history_data_count') or self.history_data_count,
                    'reference_price_source': snipe_price_result.get('reference_price_source'),
                    'adjustment_strategy': snipe_price_result.get('adjustment_strategy'),
                    'price_change_percentage': snipe_price_result.get('price_change_percentage'),
                    'estimated_profit_rate': snipe_price_result.get('estimated_profit_rate'),  # 添加推算利润率字段
                    'history_data_time_span': snipe_price_result.get('history_data_time_span'),
                    'history_data_first_date': snipe_price_result.get('history_data_first_date'),
                    'history_data_last_date': snipe_price_result.get('history_data_last_date'),
                    'decision_path': snipe_price_result.get('decision_path'),
                    'price_trend_direction': snipe_price_result.get('price_trend_direction', '平稳'),
                    'price_trend_slope': snipe_price_result.get('price_trend_slope', 0.0),
                    'price_trend_strength': snipe_price_result.get('price_trend_strength', 0.0),
                    'outlier_filter_applied': snipe_price_result.get('outlier_filter_applied', False),
                    'outlier_count': snipe_price_result.get('outlier_count', 0),
                    'reference_price_selection_method': snipe_price_result.get('reference_price_selection_method', '常卖价下一分段中位数'),
                    'reference_price_percentile': snipe_price_result.get('reference_price_percentile', 50.0),
                    'price_gap_absolute': snipe_price_result.get('price_gap_absolute', round(scan_reference_price - real_snipe_price, 2)),
                    'gap_check_result': snipe_price_result.get('gap_check_result', snipe_price_result.get('actual_price_gap_ratio') >= snipe_price_result.get('min_required_gap')),
                    'min_reference_price': snipe_price_result.get('min_reference_price', round(min(scan_reference_price, common_sell_price), 2)),
                    'min_reference_price_source': snipe_price_result.get('min_reference_price_source', '扫货参考价')
                }
                self.profit_rate_price_manager.add_record(record_data)
                logger.info(f"已添加利润率价格变动记录: 商品ID={goods_id}, 利润率={profit_rate}, "
                           f"扫货价={real_snipe_price}, 目标售价={target_sell_price}")
            
            # 检查任务的pricing_type，如果是固定利润率(2)，则根据常卖价和利润率计算扫货价格
            elif task.get('pricing_type') == 2 and task.get('profit_rate') is not None and common_sell_price > 0:
                profit_rate = task.get('profit_rate') / 100.0  # 将百分比转换为小数
                
                # 直接使用常卖价乘以(1-利润率)计算扫货价格
                real_snipe_price = common_sell_price * (1 - profit_rate)
                target_sell_price = common_sell_price
                remark = f"使用固定利润率({task.get('profit_rate')}%)和常卖价({common_sell_price})计算扫货价"
                
                logger.info(f"任务使用固定利润率定价: 商品ID={goods_id}, 利润率={task.get('profit_rate')}%, "
                           f"常卖价={common_sell_price}, 计算得到的扫货价={real_snipe_price}")
                
                # 更新任务的捡漏价和目标售价
                self.task_manager.update_task_prices(
                    task_id=task.get('id'),
                    buy_price_limit=real_snipe_price,
                    target_sell_price=target_sell_price
                )
                logger.info(f"已更新任务的捡漏价和目标售价: 任务ID={task.get('id')}, "
                           f"捡漏价={real_snipe_price}, 目标售价={target_sell_price}")
                
                # 在利润率价格变动表中添加一条自动调整记录
                record_data = {
                    'goods_id': goods_id,
                    'goods_name': task.get('name', ''),
                    'hash_name': task.get('hash_name', ''),
                    'profit_rate': profit_rate,
                    'buy_price': real_snipe_price,
                    'target_sell_price': target_sell_price,
                    'operator': 'system',
                    'remark': remark,
                    'modify_type': 1,  # 1表示自动调整
                    'pricing_type': 2,  # 2表示固定利润率
                    'common_sell_price': common_sell_price,
                    'normal_price': normal_price,
                    'price_variance': price_variance
                }
                self.profit_rate_price_manager.add_record(record_data)
                logger.info(f"已添加利润率价格变动记录: 商品ID={goods_id}, 利润率={profit_rate}, "
                           f"扫货价={real_snipe_price}, 目标售价={target_sell_price}")
            
            # 保存分析结果到数据库
            save_result = self.price_analysis_manager.add_analysis(analysis_data)
            if save_result:
                logger.info(f"成功保存商品 {goods_id} 的价格分析结果到数据库")
            else:
                logger.warning(f"保存商品 {goods_id} 的价格分析结果到数据库失败")
            
            return analysis_data
            
        except Exception as e:
            logger.error(f"保存价格分析结果失败: {goods_id}")
            logger.error(f"错误信息: {e}")
            return None
            
    def analyze_all_active_goods(self, period: str = '24h') -> List[Dict[str, Any]]:
        """
        分析所有活动商品的价格
        
        Args:
            period: 分析周期（24h/7d）
            
        Returns:
            List[Dict]: 分析结果列表
        """
        try:
            # 获取所有活动商品
            active_tasks = self.task_manager.get_active_tasks()
            results = []
            
            for task in active_tasks:
                logger.info(f"开始分析商品: {task['name']} ({task['goods_id']})")
                analysis = self.analyze_goods(task['goods_id'], period)
                if analysis:
                    results.append(analysis)
                    
            return results
            
        except Exception as e:
            logger.error(f"分析所有商品价格时出错: {str(e)}")
            return []

    def analyze_time_distribution(self, records: List[Dict]) -> Dict:
        """
        分析产品活动的时间分布，使用滑动时间窗口找出活跃时段
        
        Args:
            records: 扫描记录列表
            
        Returns:
            Dict: 时间分布统计结果，包含主要活跃时间段
        """
        if not records:
            return None
            
        # 统计每个小时的扫描次数
        hourly_stats = defaultdict(int)
        total_scans = len(records)
        
        for record in records:
            scan_time = record['scan_start_time']
            if not isinstance(scan_time, datetime):
                scan_time = datetime.strptime(scan_time, '%Y-%m-%d %H:%M:%S')
            
            hour = scan_time.hour
            hourly_stats[hour] += 1
        
        # 使用3小时滑动窗口找出活跃时段
        window_stats = []
        for start_hour in range(24):
            window_count = 0
            for offset in range(3):  # 3小时窗口
                hour = (start_hour + offset) % 24
                window_count += hourly_stats[hour]
            
            if window_count > 0:
                percentage = (window_count / total_scans) * 100
                if percentage >= 15:  # 占比超过15%的时间窗口
                    end_hour = (start_hour + 3) % 24
                    window_stats.append({
                        'time_range': f"{start_hour:02d}-{end_hour:02d}",
                        'count': window_count,
                        'percentage': round(percentage, 2)
                    })
        
        # 合并重叠的时间窗口
        merged_windows = []
        if window_stats:
            current_window = window_stats[0]
            for next_window in window_stats[1:]:
                current_start = int(current_window['time_range'].split('-')[0])
                current_end = int(current_window['time_range'].split('-')[1])
                next_start = int(next_window['time_range'].split('-')[0])
                
                # 如果时间窗口重叠，合并它们
                if next_start <= current_end:
                    current_window['time_range'] = f"{current_start:02d}-{next_window['time_range'].split('-')[1]}"
                    current_window['count'] = max(current_window['count'], next_window['count'])
                    current_window['percentage'] = round(
                        (current_window['count'] / total_scans) * 100, 2
                    )
                else:
                    merged_windows.append(current_window)
                    current_window = next_window
            
            merged_windows.append(current_window)
        
        # 按扫描次数排序
        merged_windows.sort(key=lambda x: x['count'], reverse=True)
        
        return {
            'main_active_periods': merged_windows,
            'total_scans': total_scans
        }
        
    def analyze_abnormal_price_time_distribution(self, records: List[Dict], abnormal_prices: List[float]) -> Dict:
        """
        分析异常价格的时间分布，统计每个小时异常价格出现的次数
        
        Args:
            records: 扫描记录列表
            abnormal_prices: 异常价格列表
            
        Returns:
            Dict: 异常价格的时间分布统计结果，格式为：
            {
                'hourly_stats': [
                    {
                        'hour': '08-09',  # 8点到9点
                        'count': 5,  # 出现5次异常价格
                    },
                    ...
                ],
                'total_abnormal_occurrences': 总异常价格次数
            }
        """
        if not records or not abnormal_prices:
            return None
            
        # 统计每个小时的异常价格次数
        hourly_stats = defaultdict(int)
        abnormal_set = set(abnormal_prices)  # 转换为集合以提高查找效率
        total_abnormal = 0
        
        for record in records:
            price_list = record.get('price_list', [])
            if not price_list:
                continue
                
            # 解析 price_list JSON 字符串
            try:
                if isinstance(price_list, str):
                    price_list = json.loads(price_list)
            except json.JSONDecodeError:
                logger.warning(f"解析价格列表失败: {price_list}")
                continue
                
            # 检查是否有异常价格
            abnormal_count = sum(1 for price in price_list if price in abnormal_set)
            if abnormal_count == 0:
                continue
                
            scan_time = record['scan_start_time']
            if not isinstance(scan_time, datetime):
                scan_time = datetime.strptime(scan_time, '%Y-%m-%d %H:%M:%S')
                
            hour = scan_time.hour
            hourly_stats[hour] += abnormal_count
            total_abnormal += abnormal_count
            
        # 转换成列表格式，只包含有异常价格的时段
        hourly_distribution = []
        for hour in range(24):
            count = hourly_stats[hour]
            if count > 0:
                next_hour = (hour + 1) % 24
                hourly_distribution.append({
                    'time_range': f"{hour:02d}-{next_hour:02d}",
                    'count': count
                })
        
        # 按时间顺序排序
        hourly_distribution.sort(key=lambda x: int(x['time_range'].split('-')[0]))
        
        return {
            'hourly_stats': hourly_distribution,
            'total_abnormal_occurrences': total_abnormal
        }

    def filter_outliers_from_prices(self, prices: List[float], timestamps: List[datetime] = None) -> Tuple[List[float], List[int]]:
        """
        使用K-means聚类方法过滤价格数据中的异常值
        
        Args:
            prices: 价格列表
            timestamps: 对应的时间戳列表，用于时间序列分析，可选
            
        Returns:
            Tuple[List[float], List[int]]: 过滤后的价格列表和异常值索引列表
        """
        if not prices or len(prices) < 3:
            # 数据点太少，不进行过滤
            return prices, []
            
        try:
            import numpy as np
            from sklearn.cluster import KMeans
            
            # 将价格转换为numpy数组并重塑为适合聚类的形状
            X = np.array(prices).reshape(-1, 1)
            
            # 应用K-means聚类 (K=2)
            kmeans = KMeans(n_clusters=2, random_state=42, n_init=10)
            clusters = kmeans.fit_predict(X)
            
            # 获取两个簇的中心点和大小
            cluster_centers = kmeans.cluster_centers_.flatten()
            cluster_sizes = [np.sum(clusters == i) for i in range(2)]
            
            # 计算两个簇的标准差
            cluster_stds = []
            for i in range(2):
                cluster_points = X[clusters == i].flatten()
                if len(cluster_points) > 1:
                    cluster_stds.append(np.std(cluster_points))
                else:
                    cluster_stds.append(0)
            
            # 确定哪个是异常簇
            outlier_cluster = None
            
            # 情况1: 一个簇明显小于另一个（如1-2个点 vs 5-6个点）
            if cluster_sizes[0] <= 2 and cluster_sizes[1] >= 5:
                outlier_cluster = 0
            elif cluster_sizes[1] <= 2 and cluster_sizes[0] >= 5:
                outlier_cluster = 1
            else:
                # 情况2: 两个簇大小接近，比较簇间距离和簇内离散程度
                cluster_distance = abs(cluster_centers[0] - cluster_centers[1])
                combined_std = cluster_stds[0] + cluster_stds[1]
                
                # 如果簇间距离大于两个簇内标准差之和，认为两个簇有明显区分
                if combined_std > 0 and cluster_distance > 2 * combined_std:
                    # 两极分化情况
                    # 考虑时间序列趋势，如果提供了时间戳
                    if timestamps and len(timestamps) == len(prices):
                        # 将时间戳转换为相对天数
                        base_time = min(timestamps)
                        days = [(ts - base_time).days for ts in timestamps]
                        
                        # 计算每个簇的平均时间
                        cluster0_days = [days[i] for i in range(len(clusters)) if clusters[i] == 0]
                        cluster1_days = [days[i] for i in range(len(clusters)) if clusters[i] == 1]
                        
                        avg_days_0 = np.mean(cluster0_days) if cluster0_days else 0
                        avg_days_1 = np.mean(cluster1_days) if cluster1_days else 0
                        
                        # 选择时间上更新的簇作为正常簇
                        outlier_cluster = 0 if avg_days_0 < avg_days_1 else 1
                    else:
                        # 没有时间信息，选择均值较低的簇作为正常簇（符合寻找最低扫货参考价的目标）
                        outlier_cluster = 0 if cluster_centers[0] > cluster_centers[1] else 1
                else:
                    # 簇间距离不够明显，认为没有异常值
                    return prices, []
            
            # 获取异常值的索引
            outlier_indices = [i for i in range(len(clusters)) if clusters[i] == outlier_cluster]
            
            # 获取正常值
            normal_prices = [prices[i] for i in range(len(prices)) if i not in outlier_indices]
            
            logger.info(f"价格异常值检测: 总价格点数={len(prices)}, 异常值数量={len(outlier_indices)}, "
                       f"簇1大小={cluster_sizes[0]}, 簇2大小={cluster_sizes[1]}, "
                       f"簇1中心={cluster_centers[0]:.2f}, 簇2中心={cluster_centers[1]:.2f}")
            
            return normal_prices, outlier_indices
            
        except Exception as e:
            logger.warning(f"价格异常值检测失败: {str(e)}")
            # 发生异常时返回原始价格列表
            return prices, []

    def calculate_snipe_price(self, scan_reference_price: float, profit_rate: float) -> float:
        """
        计算基础扫货价格（不考虑上下限）
        
        Args:
            scan_reference_price: 扫货参考价格
            profit_rate: 利润率（小数形式，如0.15表示15%）
            
        Returns:
            float: 计算得到的扫货价格
        """
        # 计算真实的扫货价格：扫货参考价 - (扫货参考价 × 利润率)
        real_snipe_price = scan_reference_price - (scan_reference_price * profit_rate)
        real_snipe_price = round(real_snipe_price, 2)  # 保留两位小数
        return real_snipe_price
    
    def calculate_bounded_snipe_price(self, goods_id: int, scan_reference_price: float, profit_rate: float, normal_price: float = None, custom_min_profit_rate: float = None, common_sell_price: float = None) -> Dict[str, Any]:
        """
        计算带上下限的扫货价格
        
        Args:
            goods_id: 商品ID
            scan_reference_price: 扫货参考价格
            profit_rate: 利润率（小数形式，如0.15表示15%）
            normal_price: 普通售价（官方最低价）
            custom_min_profit_rate: 最小利润率（小数形式，如0.05表示5%），如果不为None且大于0，则确保最终利润率不低于此值
            common_sell_price: 常卖价（日常售价）
            
        Returns:
            Dict: 包含调整后的扫货价格和调整说明的字典，如果普通价格缺失则返回None
        """
        # 检查普通价格是否存在
        if not normal_price or normal_price <= 0:
            logger.warning(f"商品 {goods_id} 缺少普通价格，价格更新作废")
            return None
            
         # 1. 调整利润率：根据利润率大小使用不同的调整系数，同时确保最低有4%的利润率
        if profit_rate > 0.20:  # 大于20个点
            adjustment_factor = 0.35
        elif profit_rate > 0.15:  # 大于15个点
            adjustment_factor = 0.4
        elif profit_rate > 0.10:  # 大于10个点
            adjustment_factor = 0.45
        elif profit_rate >= 0.07:  # 大于7个点
            adjustment_factor = 0.5
        else:  # 其他的
            adjustment_factor = 0.6
            
        adjusted_profit_rate = profit_rate * adjustment_factor
            
        # 判断用户自定义的最小利润率
        if custom_min_profit_rate is not None and custom_min_profit_rate > 0:
            if adjusted_profit_rate < custom_min_profit_rate:
                logger.info(f"商品 {goods_id} 的调整后利润率 {adjusted_profit_rate:.4f} 低于用户设置的最小利润率 {custom_min_profit_rate:.4f}，使用用户设置的最小利润率")
                adjusted_profit_rate = custom_min_profit_rate
        # 如果没有用户自定义的最小利润率，则使用系统默认的4%
        elif adjusted_profit_rate < 0.04:
            adjusted_profit_rate = 0.04
            logger.info(f"商品 {goods_id} 的调整后利润率 {profit_rate*adjustment_factor:.4f} 低于最低要求的4%，使用4%作为最低利润率")
        else:
            logger.info(f"商品 {goods_id} 的利润率从 {profit_rate:.4f} 调整为 {adjusted_profit_rate:.4f}，使用调整系数：{adjustment_factor}")
        
        # 2. 获取历史数据中的最小扫货参考价（上限）和价格波动性
        today = datetime.now().date()
        # history_records = self.price_analysis_manager.get_analysis_history(goods_id, days=8)
        # history_records = [record for record in history_records if record['analysis_time'].date() < today]
        # history_records = history_records[:7]
        # 修改为
        history_records = self.price_analysis_manager.get_analysis_history(goods_id, days=16)
        history_records = [record for record in history_records if record['analysis_time'].date() < today]
        history_records = history_records[:15]
        
        price_variance = 0.0  # 默认波动性为0
        
        # 如果历史记录不足，使用当前扫货参考价
        if not history_records:
            logger.info(f"商品 {goods_id} 没有历史记录，使用当前扫货参考价")
            min_reference_price = scan_reference_price
            history_count = 0
        else:
            # 提取所有历史扫货参考价和对应的时间戳
            history_reference_prices = []
            history_timestamps = []
            for record in history_records:
                if 'scan_reference_price' in record and record['scan_reference_price']:
                    history_reference_prices.append(record['scan_reference_price'])
                    # 如果记录中有时间戳，则添加到时间戳列表
                    if 'timestamp' in record and record['timestamp']:
                        history_timestamps.append(record['timestamp'])
                    else:
                        # 如果没有时间戳，使用当前时间减去索引值（作为近似的时间序列）
                        history_timestamps.append(datetime.now() - timedelta(hours=len(history_timestamps)))
                # 获取最新的价格波动性数据
                if 'price_variance' in record and record['price_variance'] is not None:
                    price_variance = record['price_variance']
                    break  # 只使用最新的价格波动性
            
            # 如果没有有效的历史扫货参考价，使用当前扫货参考价
            if not history_reference_prices:
                min_reference_price = scan_reference_price
                history_count = 0
            else:
                # 应用异常值过滤
                filtered_prices, outlier_indices = self.filter_outliers_from_prices(history_reference_prices, history_timestamps)
                
                if outlier_indices:
                    logger.info(f"商品 {goods_id} 的历史扫货参考价中检测到 {len(outlier_indices)} 个异常值，"
                               f"原始价格: {history_reference_prices}, 过滤后价格: {filtered_prices}")
                
                # 使用趋势感知定价方法选择参考价格
                if filtered_prices:
                    # 分析价格趋势
                    trend_result = self.analyze_price_trend(filtered_prices, history_timestamps)
                    trend_direction = trend_result['direction']
                    trend_slope = trend_result['slope']
                    trend_strength = trend_result['strength']
                    
                    # 根据趋势方向选择参考价格
                    import numpy as np

                    # 保存选择的百分位数，用于记录
                    selected_percentile = 50  # 默认使用中位数

                    if trend_direction == 'strong_down':
                        # 强下降趋势，使用更低百分位数
                        selected_percentile = 5
                        min_reference_price = np.percentile(filtered_prices, selected_percentile)
                        logger.info(f"商品 {goods_id} 价格呈强下降趋势(斜率={trend_slope:.6f}, 强度={trend_strength:.4f})，"
                                f"使用{selected_percentile}%百分位数作为参考价: {min_reference_price:.2f}")
                    elif trend_direction == 'down':
                        # 下降趋势，使用10%百分位数
                        selected_percentile = 10
                        min_reference_price = np.percentile(filtered_prices, selected_percentile)
                        logger.info(f"商品 {goods_id} 价格呈下降趋势(斜率={trend_slope:.6f}, 强度={trend_strength:.4f})，"
                                f"使用{selected_percentile}%百分位数作为参考价: {min_reference_price:.2f}")
                    elif trend_direction == 'strong_up':
                        # 强上升趋势，使用较高百分位数
                        selected_percentile = 75
                        min_reference_price = np.percentile(filtered_prices, selected_percentile)
                        logger.info(f"商品 {goods_id} 价格呈强上升趋势(斜率={trend_slope:.6f}, 强度={trend_strength:.4f})，"
                                f"使用{selected_percentile}%百分位数作为参考价: {min_reference_price:.2f}")
                    elif trend_direction == 'up':
                        # 弱上升趋势，使用稍高百分位数
                        selected_percentile = 65
                        min_reference_price = np.percentile(filtered_prices, selected_percentile)
                        logger.info(f"商品 {goods_id} 价格呈上升趋势(斜率={trend_slope:.6f}, 强度={trend_strength:.4f})，"
                                f"使用{selected_percentile}%百分位数作为参考价: {min_reference_price:.2f}")
                    else:
                        # 稳定趋势，使用中位数
                        selected_percentile = 50
                        min_reference_price = np.median(filtered_prices)
                        logger.info(f"商品 {goods_id} 价格呈稳定趋势(斜率={trend_slope:.6f}, 强度={trend_strength:.4f})，"
                                f"使用中位数作为参考价: {min_reference_price:.2f}")

                    # 保存选择的百分位数，用于记录
                    self.reference_price_percentile = selected_percentile
                else:
                    # 如果过滤后没有价格（极端情况），则使用原始价格的中位数
                    import numpy as np
                    min_reference_price = np.median(history_reference_prices)
                    logger.info(f"商品 {goods_id} 过滤后没有有效价格，使用原始历史价格的中位数: {min_reference_price:.2f}")
                
                history_count = len(history_reference_prices)
        
        # 计算基础扫货价
        base_snipe_price = self.calculate_snipe_price(min_reference_price, adjusted_profit_rate)
        # 3. 计算对数比例调整系数和波动性影响
        # 参数设置
        upper_base_adjust = 0.005  # 上限基础调整系数 (0.5%)
        lower_base_adjust = 0.005  # 下限基础调整系数 (0.5%)
        log_constant = 15.0  # 对数常数
        volatility_weight = 0.5  # 波动性权重
        max_adjust = 0.01  # 最大调整系数 (1%)
        
        # 对数比例调整计算
        upper_log_adjust = upper_base_adjust / math.log10(scan_reference_price + log_constant)
        lower_log_adjust = lower_base_adjust / math.log10(scan_reference_price + log_constant)
        
        # 波动性影响计算
        volatility_impact = 1.0 + (volatility_weight * price_variance)
        
        # 最终调整系数计算（限制最大值）
        upper_adjust = min(upper_log_adjust * volatility_impact, max_adjust)
        lower_adjust = min(lower_log_adjust * volatility_impact, max_adjust)
        
        logger.info(f"商品 {goods_id} 的价格调整系数 - 上限: {upper_adjust:.4f}, 下限: {lower_adjust:.4f}, "
                   f"价格: {scan_reference_price}, 波动性: {price_variance:.4f}")
        
        # 4. 计算上限和下限价格
        # 计算上限扫货价
        upper_bound_price = self.calculate_snipe_price(min_reference_price, adjusted_profit_rate)
        adjusted_upper_bound = upper_bound_price * (1.0 - upper_adjust)
        
        # 确定下限（普通售价）
        adjusted_lower_bound = normal_price * (1.0 + lower_adjust)
        
        # 检查上限和下限价格是否太近
        price_gap = scan_reference_price - adjusted_lower_bound
        price_gap_ratio = price_gap / scan_reference_price if scan_reference_price > 0 else 0
        
        # 使用固定的4%作为最小所需间距比例，而不是动态计算
        # 价格越高，间距比例越小，但不低于4%
        min_required_gap = 0.04  # 固定为4%
        
        # 记录动态计算的间距比例，作为推算利润率，仅用于记录和分析，不影响判断逻辑
        estimated_profit_rate = self.calculate_dynamic_gap_ratio(goods_id, scan_reference_price, normal_price)
        
        # 判断是否应用价格调整
        apply_price_adjustment = True
        if price_gap_ratio < min_required_gap:
            apply_price_adjustment = False
            logger.info(f"商品 {goods_id} 的扫货参考价 {scan_reference_price:.2f} 和下限价格 {adjusted_lower_bound:.2f} 间距太小，" 
                       f"间距比例 {price_gap_ratio*100:.2f}% 小于固定最小间距 4%，使用原始扫货价")
            
        # 5. 新的价格调整逻辑
        adjusted_snipe_price = base_snipe_price
        adjustment_reason = f"基础扫货价: {base_snipe_price:.2f}"
        
        # 只有当上限和下限间距足够大时，才应用价格调整
        if apply_price_adjustment:
            # 情况1: 基础扫货价低于普通价格，在普通价格基础上按照调整比例提高
            if base_snipe_price < normal_price:
                old_price = base_snipe_price
                adjusted_snipe_price = normal_price * (1.0 + lower_adjust)
                adjustment_reason = f"基础扫货价 {base_snipe_price:.2f} 低于普通价格 {normal_price:.2f}，" \
                                   f"在普通价格基础上提高 {lower_adjust*100:.2f}%，调整为: {adjusted_snipe_price:.2f}"
                logger.info(f"商品 {goods_id} 的扫货价应用下限约束: {old_price:.2f} -> {adjusted_snipe_price:.2f}")
            
            # 情况2: 基础扫货价高于普通价格且高于上限，在上限基础上按照调整比例降低
            elif base_snipe_price > adjusted_upper_bound:
                old_price = base_snipe_price
                adjusted_snipe_price = adjusted_upper_bound
                
                # 如果降低后的价格低于普通价格，则在普通价格基础上按照调整比例提高
                if adjusted_snipe_price < normal_price:
                    adjusted_snipe_price = normal_price * (1.0 + lower_adjust)
                    adjustment_reason = f"基础扫货价 {base_snipe_price:.2f} 高于上限 {adjusted_upper_bound:.2f}，" \
                                       f"但调整后低于普通价格 {normal_price:.2f}，在普通价格基础上提高 {lower_adjust*100:.2f}%，" \
                                       f"调整为: {adjusted_snipe_price:.2f}"
                else:
                    adjustment_reason = f"基础扫货价 {base_snipe_price:.2f} 高于上限 {adjusted_upper_bound:.2f}，" \
                                       f"调整为上限价格: {adjusted_snipe_price:.2f}"
                
                logger.info(f"商品 {goods_id} 的扫货价应用上限约束: {old_price:.2f} -> {adjusted_snipe_price:.2f}")
        else:
            # 上限和下限价格间距太小，使用原始基础扫货价
            adjustment_reason = f"基础扫货价 {base_snipe_price:.2f}，扫货参考价 {scan_reference_price:.2f} 和下限价格 {adjusted_lower_bound:.2f} 间距太小" \
                              f"（{price_gap_ratio*100:.2f}% < 4%），保持原始扫货价"
            
        
            
        # 构建结果
        result = {
            'snipe_price': round(adjusted_snipe_price, 2),
            'base_snipe_price': round(base_snipe_price, 2),
            'upper_bound_price': round(upper_bound_price, 2),
            'adjusted_upper_bound': round(adjusted_upper_bound, 2),
            'lower_bound_price': normal_price,
            'adjusted_lower_bound': round(adjusted_lower_bound, 2),
            'upper_adjust_factor': round(upper_adjust, 4),
            'lower_adjust_factor': round(lower_adjust, 4),
            'price_variance': round(price_variance, 4),
            'history_data_count': self.history_data_count,
            'remark': f'自动调整 - {adjustment_reason}',
            'estimated_profit_rate': estimated_profit_rate  # 添加推算利润率字段
        }
        
        # 添加异常值过滤相关信息
        if 'outlier_indices' in locals() and outlier_indices:
            result['outlier_filter_applied'] = True
            result['outlier_count'] = len(outlier_indices)
            result['original_history_prices'] = [round(p, 2) for p in history_reference_prices] if 'history_reference_prices' in locals() else []
            result['filtered_history_prices'] = [round(p, 2) for p in filtered_prices] if 'filtered_prices' in locals() else []
        else:
            result['outlier_filter_applied'] = False
            result['outlier_count'] = 0
        
        # 添加动态价格调整的新增字段
        # 1. 计算得到的动态最小间距比例值
        result['min_required_gap'] = round(min_required_gap, 4)
        
        # 2. 实际价格间距比例
        result['actual_price_gap_ratio'] = round(price_gap_ratio, 4)
        
        # 3. 动态间距计算使用的历史数据记录数量
        result['history_data_count'] = self.history_data_count
        
        # 4. 扫货参考价来源
        # 根据参考价来源统计信息确定主要来源
        if hasattr(self, 'reference_price_source_stats') and self.reference_price_source_stats['总数'] > 0:
            common_sell_price_count = self.reference_price_source_stats['常卖价替代']
            original_price_count = self.reference_price_source_stats['原始']
            
            # 如果常卖价替代的比例超过50%，则标记为"常卖价替代"
            if common_sell_price_count > 0 and common_sell_price_count / self.reference_price_source_stats['总数'] >= 0.5:
                result['reference_price_source'] = "常卖价替代"
            else:
                result['reference_price_source'] = "原始"
                
            # 添加详细的来源统计信息
            result['reference_price_source_detail'] = {
                '常卖价替代数量': common_sell_price_count,
                '原始数量': original_price_count,
                '总记录数': self.reference_price_source_stats['总数']
            }
        else:
            result['reference_price_source'] = "原始"
        
        # 5. 采用的价格调整策略
        if not apply_price_adjustment:
            result['adjustment_strategy'] = "原始扫货价"
        elif base_snipe_price < normal_price:
            result['adjustment_strategy'] = "下限约束"
        elif base_snipe_price > adjusted_upper_bound:
            result['adjustment_strategy'] = "上限约束"
        else:
            result['adjustment_strategy'] = "无需调整"
        
        # 6. 调整前后的价格变化幅度（百分比）
        if base_snipe_price > 0:
            price_change = (adjusted_snipe_price - base_snipe_price) / base_snipe_price
            result['price_change_percentage'] = round(price_change * 100, 2)  # 转换为百分比并保留两位小数
        else:
            result['price_change_percentage'] = 0.0
        
        # 添加价格趋势信息
        if 'trend_direction' in locals() and 'trend_slope' in locals() and 'trend_strength' in locals():
            result['price_trend_direction'] = trend_direction
            result['price_trend_slope'] = round(trend_slope, 6)
            result['price_trend_strength'] = round(trend_strength, 4)
        else:
            result['price_trend_direction'] = '平稳'
            result['price_trend_slope'] = 0.0
            result['price_trend_strength'] = 0.0
        
        # 添加参考价格选择逻辑
        if 'trend_direction' in locals():
            if trend_direction == 'strong_down':
                result['reference_price_selection_method'] = 'percentile'
                result['reference_price_percentile'] = 5.0
            elif trend_direction == 'down':
                result['reference_price_selection_method'] = 'percentile'
                result['reference_price_percentile'] = 10.0
            elif trend_direction == 'strong_up':
                result['reference_price_selection_method'] = 'percentile'
                result['reference_price_percentile'] = 75.0
            elif trend_direction == 'up':
                result['reference_price_selection_method'] = 'percentile'
                result['reference_price_percentile'] = 65.0
            else:  # stable
                result['reference_price_selection_method'] = 'median'
                result['reference_price_percentile'] = 50.0
        else:
            result['reference_price_selection_method'] = 'current'
            result['reference_price_percentile'] = None

        # 添加最小参考价格信息
        result['min_reference_price'] = round(min_reference_price, 2)
        if not history_records:
            result['min_reference_price_source'] = '当前扫货参考价'
        elif 'trend_direction' in locals():
            if trend_direction == 'strong_down':
                result['min_reference_price_source'] = '历史5%百分位数'
            elif trend_direction == 'down':
                result['min_reference_price_source'] = '历史10%百分位数'
            elif trend_direction == 'strong_up':
                result['min_reference_price_source'] = '历史75%百分位数'
            elif trend_direction == 'up':
                result['min_reference_price_source'] = '历史65%百分位数'
            else:
                result['min_reference_price_source'] = '历史中位数'
        else:
            result['min_reference_price_source'] = '历史中位数（无趋势数据）'
        
        # 添加价格间距判断详情
        result['price_gap_absolute'] = round(price_gap, 2)
        result['gap_check_result'] = apply_price_adjustment
        
        # 添加安全检查信息
        min_profit_rate = 0.03  # 默认最小利润率保障（3%）

        # 根据价格趋势动态调整最小利润率要求
        if 'trend_direction' in locals():
            if trend_direction == 'strong_up':
                # 强上升趋势，可以接受更低的利润率
                min_profit_rate = 0.01  # 1%
                logger.info(f"商品 {goods_id} 价格呈强上升趋势，降低最小利润率要求至1%")
            elif trend_direction == 'up':
                # 上升趋势，稍微降低利润率要求
                min_profit_rate = 0.02  # 2%
                logger.info(f"商品 {goods_id} 价格呈上升趋势，降低最小利润率要求至2%")

        min_profit_check_applied = False
        original_profit_rate = adjusted_profit_rate

        # # 检查调整后的价格是否能保证最小利润率
        # if adjusted_snipe_price > 0 and adjusted_upper_bound > 0:
        #     actual_profit_rate = (adjusted_upper_bound - adjusted_snipe_price) / adjusted_upper_bound
        #     if actual_profit_rate < min_profit_rate:
        #         min_profit_check_applied = True
        #         safe_price = adjusted_upper_bound * (1 - min_profit_rate)
        #         old_price = adjusted_snipe_price
        #         adjusted_snipe_price = safe_price
        #         result['snipe_price'] = round(adjusted_snipe_price, 2)
        #         result['remark'] += f"，应用最小利润率保障({min_profit_rate*100:.0f}%)，从 {old_price:.2f} 调整为 {safe_price:.2f}"
        #         logger.info(f"商品 {goods_id} 应用最小利润率保障({min_profit_rate*100:.0f}%): {old_price:.2f} -> {safe_price:.2f}")
                

        # # 确保扫货价格不低于下限价格（无论是否应用了最小利润率保障）
        # if adjusted_snipe_price < adjusted_lower_bound:
        #     old_price = adjusted_snipe_price
        #     adjusted_snipe_price = adjusted_lower_bound
        #     result['snipe_price'] = round(adjusted_snipe_price, 2)  # 更新结果中的扫货价格
        #     if min_profit_check_applied:
        #         adjustment_reason += f"，扫货价在应用3%利润率保障后仍低于下限价格，从 {old_price:.2f} 调整为下限价格 {adjusted_lower_bound:.2f}"
        #         logger.info(f"商品 {goods_id} 扫货价在应用3%利润率保障后仍低于下限价格，调整为下限价格: {old_price:.2f} -> {adjusted_lower_bound:.2f}")
        #     else:
        #         adjustment_reason += f"，扫货价低于下限价格，从 {old_price:.2f} 调整为下限价格 {adjusted_lower_bound:.2f}"
        #         logger.info(f"商品 {goods_id} 扫货价低于下限价格，调整为下限价格: {old_price:.2f} -> {adjusted_lower_bound:.2f}")
        
        # 检查调整后的价格是否能保证最小利润率
        user_min_profit_rate_applied = False
        min_profit_check_applied = False

        if adjusted_snipe_price > 0 and adjusted_upper_bound > 0:
            actual_profit_rate = (adjusted_upper_bound - adjusted_snipe_price) / adjusted_upper_bound
            
            # 如果用户设置了自定义最小利润率，并且实际利润率低于用户设置的最小利润率
            if custom_min_profit_rate is not None and custom_min_profit_rate > 0 and actual_profit_rate < custom_min_profit_rate:
                # 使用常卖价（日常售价）作为基数计算扫货价格
                safe_price = common_sell_price * (1 - custom_min_profit_rate)
                old_price = adjusted_snipe_price
                adjusted_snipe_price = safe_price
                result['snipe_price'] = round(adjusted_snipe_price, 2)
                result['remark'] += f"，应用用户设置的最小利润率({custom_min_profit_rate*100:.2f}%)，从 {old_price:.2f} 调整为 {safe_price:.2f}"
                logger.info(f"商品 {goods_id} 应用用户设置的最小利润率({custom_min_profit_rate*100:.2f}%)，使用常卖价 {common_sell_price:.2f} 作为基数: {old_price:.2f} -> {safe_price:.2f}")
                            
                # 标记已应用用户自定义最小利润率，后续不再根据普通价格调整
                user_min_profit_rate_applied = True
            # 否则使用系统默认的最小利润率保障
            elif actual_profit_rate < min_profit_rate:
                min_profit_check_applied = True
                safe_price = adjusted_upper_bound * (1 - min_profit_rate)
                old_price = adjusted_snipe_price
                adjusted_snipe_price = safe_price
                result['snipe_price'] = round(adjusted_snipe_price, 2)
                result['remark'] += f"，应用最小利润率保障({min_profit_rate*100:.0f}%)，从 {old_price:.2f} 调整为 {safe_price:.2f}"
                logger.info(f"商品 {goods_id} 应用最小利润率保障({min_profit_rate*100:.0f}%): {old_price:.2f} -> {safe_price:.2f}")
        

        # 确保扫货价格不低于下限价格（仅当没有应用用户自定义最小利润率时）
        if not user_min_profit_rate_applied:
            if adjusted_snipe_price < adjusted_lower_bound:
                old_price = adjusted_snipe_price
                adjusted_snipe_price = adjusted_lower_bound
                result['snipe_price'] = round(adjusted_snipe_price, 2)  # 更新结果中的扫货价格
                if min_profit_check_applied:
                    adjustment_reason += f"，扫货价在应用最小利润率保障后仍低于下限价格，从 {old_price:.2f} 调整为下限价格 {adjusted_lower_bound:.2f}"
                    logger.info(f"商品 {goods_id} 扫货价在应用最小利润率保障后仍低于下限价格，调整为下限价格: {old_price:.2f} -> {adjusted_lower_bound:.2f}")
                else:
                    adjustment_reason += f"，扫货价低于下限价格，从 {old_price:.2f} 调整为下限价格 {adjusted_lower_bound:.2f}"
                    logger.info(f"商品 {goods_id} 扫货价低于下限价格，调整为下限价格: {old_price:.2f} -> {adjusted_lower_bound:.2f}")
        
        result['min_profit_check_applied'] = min_profit_check_applied
        result['original_profit_rate'] = round(original_profit_rate, 4)
        
        # 添加历史数据统计信息
        if hasattr(self, 'history_data_time_span'):
            result['history_data_time_span'] = self.history_data_time_span
        if hasattr(self, 'history_data_first_date') and self.history_data_first_date:
            result['history_data_first_date'] = self.history_data_first_date
        if hasattr(self, 'history_data_last_date') and self.history_data_last_date:
            result['history_data_last_date'] = self.history_data_last_date
        
        # 添加决策路径信息
        if hasattr(self, 'decision_path'):
            result['decision_path'] = self.decision_path
        else:
            result['decision_path'] = "使用固定间距比例4%"
        
        # 确保所有可能为NULL的字段都有默认值
        if 'outlier_filter_applied' not in result:
            result['outlier_filter_applied'] = False
        if 'outlier_count' not in result:
            result['outlier_count'] = 0
        if 'price_gap_absolute' not in result:
            result['price_gap_absolute'] = round(scan_reference_price - adjusted_snipe_price, 2)
        if 'gap_check_result' not in result:
            result['gap_check_result'] = price_gap_ratio >= min_required_gap
            
        # 添加更多缺失字段的默认值
        if 'price_trend_direction' not in result:
            result['price_trend_direction'] = '平稳'
        if 'price_trend_slope' not in result:
            result['price_trend_slope'] = 0.0
        if 'price_trend_strength' not in result:
            result['price_trend_strength'] = 0.0
        if 'reference_price_selection_method' not in result:
            result['reference_price_selection_method'] = '常卖价下一分段中位数'
        if 'reference_price_percentile' not in result:
            result['reference_price_percentile'] = 50.0
        if 'min_reference_price' not in result:
            result['min_reference_price'] = round(min(scan_reference_price, common_sell_price), 2)
        if 'min_reference_price_source' not in result:
            result['min_reference_price_source'] = '扫货参考价'
            
        return result

    def calculate_dynamic_gap_ratio(self, goods_id: int, current_reference_price: float, current_normal_price: float) -> float:
        """
        根据历史的扫货参考价格和普通售价计算动态价格间距参数
        
        Args:
            goods_id: 商品ID
            current_reference_price: 当前扫货参考价格
            current_normal_price: 当前普通售价（官方最低价）
            
        Returns:
            float: 动态计算的实际间距比例，基于历史数据分析
        """
        try:
            # 获取商品的历史分析数据
            today = datetime.now().date()
            history_data = self.price_analysis_manager.get_analysis_history_all(goods_id)
            history_data = [record for record in history_data if record['analysis_time'].date() < today]
            
            # 限制历史数据数量，最多使用最近30天的数据
            max_days = 30
            history_data = history_data[:max_days]
            
            # 记录历史数据的时间跨度信息
            history_data_count = len(history_data)
            
            # 处理历史数据的日期信息
            if history_data:
                # 获取最早和最晚的日期
                earliest_date = min([record['analysis_time'].date() for record in history_data])
                latest_date = max([record['analysis_time'].date() for record in history_data])
                
                # 计算时间跨度（天数）
                time_span = (latest_date - earliest_date).days + 1
                
                # 保存日期信息到类属性（直接保存date对象，而不是字符串）
                self.history_data_first_date = earliest_date
                self.history_data_last_date = latest_date
                self.history_data_time_span = time_span
                
                logger.info(f"商品 {goods_id} 历史数据时间跨度: {time_span}天，从 {earliest_date} 到 {latest_date}")
            else:
                # 如果没有历史数据，设置为None
                self.history_data_first_date = None
                self.history_data_last_date = None
                self.history_data_time_span = 0
                
                logger.info(f"商品 {goods_id} 没有历史数据")
            
            # 重置参考价来源统计，确保每个商品都有自己的统计数据
            self.reference_price_source_stats = {
                '常卖价替代': 0,
                '原始': 0,
                '总数': 0
            }
            
            # 如果历史记录不足，使用反比例函数作为默认值
            if not history_data or len(history_data) < 3:
                logger.info(f"商品 {goods_id} 历史数据不足({len(history_data)}条)，使用反比例函数计算默认间距比例")
                # 使用反比例函数计算默认值，不限制范围
                default_ratio = 1 / (current_reference_price / 10 + 1)
                
                # 记录决策路径
                self.decision_path = "历史数据不足，使用反比例函数计算默认间距比例"
                
                # 返回计算结果
                return default_ratio
            
            # 提取历史数据中的价格信息
            valid_records = []
            for record in history_data:
                ref_price = record.get('scan_reference_price')
                normal_price = record.get('normal_price')
                
                # 如果扫货参考价为空，尝试使用常卖价替代
                if (ref_price is None or ref_price <= 0) and record.get('common_sell_price') is not None and record.get('common_sell_price') > 0:
                    ref_price = record.get('common_sell_price')
                    self.reference_price_source_stats['常卖价替代'] += 1
                    self.reference_price_source_stats['总数'] += 1
                elif ref_price is not None and ref_price > 0:
                    self.reference_price_source_stats['原始'] += 1
                    self.reference_price_source_stats['总数'] += 1
                
                # 只保留有效的价格记录
                if ref_price is not None and ref_price > 0 and normal_price is not None and normal_price > 0 and ref_price > normal_price:
                    gap_ratio = (ref_price - normal_price) / ref_price
                    valid_records.append({
                        'reference_price': ref_price,
                        'normal_price': normal_price,
                        'gap_ratio': gap_ratio,
                        'date': record.get('analysis_time').date()
                    })
            
            # 如果有效记录不足3条，使用反比例函数作为默认值
            if len(valid_records) < 3:
                logger.info(f"商品 {goods_id} 有效价格记录不足({len(valid_records)}条)，使用反比例函数计算默认间距比例")
                # 使用反比例函数计算默认值，不限制范围
                default_ratio = 1 / (current_reference_price / 10 + 1)
                
                # 记录决策路径
                self.decision_path = "有效价格记录不足，使用反比例函数计算默认间距比例"
                
                # 返回计算结果
                return default_ratio
            
            # 计算间距比例的统计值
            gap_ratios = [record['gap_ratio'] for record in valid_records]
            
            # 检测并过滤异常值
            q1 = np.percentile(gap_ratios, 25)
            q3 = np.percentile(gap_ratios, 75)
            iqr = q3 - q1
            lower_bound = q1 - 1.5 * iqr
            upper_bound = q3 + 1.5 * iqr
            
            # 过滤异常值
            filtered_ratios = [r for r in gap_ratios if lower_bound <= r <= upper_bound]
            outlier_count = len(gap_ratios) - len(filtered_ratios)
            outlier_filter_applied = outlier_count > 0
            
            # 如果过滤后没有价格（极端情况），则使用原始数据
            if len(filtered_ratios) < 3:
                filtered_ratios = gap_ratios
                outlier_filter_applied = False
                outlier_count = 0
                logger.info(f"商品 {goods_id} 过滤异常值后数据太少，使用原始数据")
            
            # 计算加权平均值（40%平均值 + 60%中位数）
            mean_ratio = np.mean(filtered_ratios)
            median_ratio = np.median(filtered_ratios)
            weighted_ratio = 0.4 * mean_ratio + 0.6 * median_ratio
            
            # 根据当前价格水平进行微调
            # 价格越高，间距比例越小，但不低于4%
            price_factor = 1.0
            if current_reference_price > 100:
                price_factor = 0.9
            elif current_reference_price > 500:
                price_factor = 0.8
            
            final_ratio = weighted_ratio * price_factor
            
            # 确保最小间距不低于4%
            final_ratio = max(final_ratio, 0.04)
            
            # 记录决策路径
            self.decision_path = f"基于{len(filtered_ratios)}条历史数据计算动态间距比例，"
            if outlier_filter_applied:
                self.decision_path += f"过滤了{outlier_count}个异常值，"
            self.decision_path += f"加权平均(均值{mean_ratio:.4f}*0.4+中位数{median_ratio:.4f}*0.6)*价格因子{price_factor}={final_ratio:.4f}"
            
            # 记录参考价来源统计
            logger.info(f"商品 {goods_id} 参考价来源统计: {self.reference_price_source_stats}")
            
            # 保存历史数据统计信息
            self.history_data_time_span = (self.history_data_last_date - self.history_data_first_date).days if self.history_data_first_date and self.history_data_last_date else 0
            self.history_data_count = history_data_count
            self.outlier_filter_applied = outlier_filter_applied
            self.outlier_count = outlier_count
            self.reference_price_percentile = 50  # 默认使用中位数
            
            return final_ratio
            
        except Exception as e:
            logger.warning(f"计算动态间距比例时发生错误: {str(e)}")
            # 发生异常时返回默认值
            self.decision_path = f"计算出错({str(e)}), 使用反比例函数计算默认间距比例"
            return 1 / (current_reference_price / 10 + 1)
    
    def analyze_price_trend(self, prices: List[float], timestamps: List[datetime] = None) -> Dict[str, Any]:
        """
        分析价格趋势，使用线性回归计算趋势方向和强度
        
        Args:
            prices: 价格列表
            timestamps: 对应的时间戳列表，用于时间序列分析，可选
            
        Returns:
            Dict: 包含趋势方向('strong_up', 'up', 'stable', 'down', 'strong_down')、斜率和强度的字典
        """
        try:
            import numpy as np
            from scipy import stats
            
            # 如果价格数据不足，无法判断趋势
            if not prices or len(prices) < 2:
                return {
                    'direction': 'stable',
                    'slope': 0.0,
                    'strength': 0.0
                }
            
            # 准备时间序列数据
            if timestamps and len(timestamps) == len(prices):
                # 将时间戳转换为相对天数
                base_time = min(timestamps)
                days = [(ts - base_time).total_seconds() / (24 * 3600) for ts in timestamps]
            else:
                # 如果没有时间戳，使用等间距的索引
                days = list(range(len(prices)))
            
            # 使用线性回归分析趋势
            slope, intercept, r_value, p_value, std_err = stats.linregress(days, prices)
            
            # 计算趋势强度（使用R平方值，表示拟合优度）
            strength = r_value ** 2
            
            # 计算平均价格和价格变化百分比
            avg_price = np.mean(prices)
            price_change_pct = (slope * len(days)) / avg_price if avg_price > 0 else 0
            
            # 判断趋势方向和强度
            if p_value < 0.1:  # 90%置信度
                if slope > 0:
                    # 上升趋势 - 进一步细分强度
                    if strength > 0.6 or price_change_pct > 0.05:  # 强上升趋势
                        direction = 'strong_up'
                    else:  # 弱上升趋势
                        direction = 'up'
                else:
                    # 下降趋势 - 进一步细分强度
                    if strength > 0.6 or price_change_pct < -0.05:  # 强下降趋势
                        direction = 'strong_down'
                    else:  # 弱下降趋势
                        direction = 'down'
            else:
                # p值较大，趋势不显著
                direction = 'stable'
            
            # 如果斜率非常小（接近于0），也视为稳定
            if abs(slope) < 0.01 * np.mean(prices):
                direction = 'stable'
            
            return {
                'direction': direction,
                'slope': slope,
                'strength': strength,
                'p_value': p_value,
                'r_squared': strength,
                'price_change_pct': price_change_pct
            }
            
        except Exception as e:
            logger.warning(f"价格趋势分析失败: {str(e)}")
            # 发生异常时返回稳定趋势
            return {
                'direction': 'stable',
                'slope': 0.0,
                'strength': 0.0,
                'error': str(e)
            }

if __name__ == "__main__":
    # 测试单个任务饰品的固定利润率功能
    analyzer = ScanRecordPriceAnalyzer()
    
    # 获取一个测试任务
    task_manager = TaskManager()
    test_task_id = 2285  # 替换为实际存在的任务ID
    
    # 获取任务信息
    task = task_manager.get_task_by_id(test_task_id)
    if not task:
        logger.error(f"未找到ID为 {test_task_id} 的任务")
        exit(1)
    
    # 显示任务信息
    logger.info(f"测试任务信息:")
    logger.info(f"ID: {task['id']}")
    logger.info(f"商品ID: {task['goods_id']}")
    logger.info(f"商品名称: {task['name']}")
    logger.info(f"当前定价类型: {task['pricing_type']} (0:固定价格 1:动态利润率 2:固定利润率)")
    logger.info(f"当前利润率: {task['profit_rate']}%")
    logger.info(f"当前捡漏价: {task['buy_price_limit']}")
    logger.info(f"当前目标售价: {task['target_sell_price']}")
    
    # 临时修改任务为固定利润率类型进行测试
    original_pricing_type = task['pricing_type']
    original_profit_rate = task['profit_rate']
    

    
    try:
        # 分析商品
        logger.info(f"开始分析商品 {task['goods_id']}...")
        result = analyzer.analyze_goods(task['goods_id'])
        
        if not result:
            logger.error(f"分析商品 {task['goods_id']} 失败")
        else:
            # 提取分析结果
            common_sell_price = result.get('common_sell_price')
            
            # 获取更新后的任务信息
            updated_task = task_manager.get_task_by_id(test_task_id)
            
            logger.info(f"\n分析结果:")
            logger.info(f"常卖价格: {common_sell_price}")
            logger.info(f"利润率: {updated_task['profit_rate']}%")
            logger.info(f"计算的扫货价: {updated_task['buy_price_limit']}")
            logger.info(f"目标售价: {updated_task['target_sell_price']}")
            
            # 验证计算结果
            expected_buy_price = common_sell_price * (1 - updated_task['profit_rate'] / 100.0)
            logger.info(f"预期扫货价: {expected_buy_price:.2f}")
            logger.info(f"实际扫货价: {updated_task['buy_price_limit']:.2f}")
            logger.info(f"差异: {abs(expected_buy_price - updated_task['buy_price_limit']):.2f}")
            
            # 获取最新的利润率价格记录
            profit_rate_manager = ProfitRatePriceManager()
            latest_record = profit_rate_manager.get_latest_record(task['goods_id'])
            
            if latest_record:
                logger.info(f"\n最新利润率价格记录:")
                logger.info(f"记录ID: {latest_record['id']}")
                logger.info(f"商品ID: {latest_record['goods_id']}")
                logger.info(f"利润率: {latest_record['profit_rate'] * 100:.2f}%")
                logger.info(f"扫货价: {latest_record['buy_price']}")
                logger.info(f"目标售价: {latest_record['target_sell_price']}")
                logger.info(f"定价类型: {latest_record['pricing_type']} (0:固定价格 1:动态利润率 2:固定利润率)")
                logger.info(f"备注: {latest_record['remark']}")
            else:
                logger.warning(f"未找到商品 {task['goods_id']} 的利润率价格记录")
    
    finally:
        # 由于我们没有修改任务设置，所以不需要恢复
        pass